home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / motif / ohidden.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  10KB  |  357 lines

  1. /*
  2.  * Copyright (c) 1993-94, Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that the name of Silicon Graphics may not be used in any advertising or
  7.  * publicity relating to the software without the specific, prior written
  8.  * permission of Silicon Graphics.
  9.  *
  10.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  11.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  12.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  13.  *
  14.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  15.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  16.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  17.  * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
  18.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19.  *
  20.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  21.  */
  22. /*----------------------------------------------------------------------------
  23.  *
  24.  * ohidden.c : openGL (motif) example showing how to use stencils
  25.  *             to draw outlined polygons.
  26.  *
  27.  * Author : Yusuf Attarwala
  28.  *          SGI - Applications
  29.  * Date   : Jul 93
  30.  *
  31.  *    note : the main intent of this program is to demo the stencil
  32.  *           plane functionality, hence the rendering is kept
  33.  *           simple (wireframe).
  34.  *
  35.  *    press  left   button for animation
  36.  *    press  middle button to turn OFF stenciling
  37.  *    press  right  button to turn ON  stenciling
  38.  *
  39.  *---------------------------------------------------------------------------*/
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43.  
  44. #include <Xm/Xm.h> 
  45. #include <Xm/Frame.h>               /* for frame widgets */
  46. #include <Xm/Form.h>               /* for frame widgets */
  47. #include <X11/keysym.h>             /* keyboard translations */
  48. #include <X11/StringDefs.h>
  49.  
  50. #include <GL/gl.h>                  /* gl includes */
  51. #include <GL/glu.h>                 /* utility library includes */
  52. #include <GL/GLwMDrawA.h>           /* include for the drawing area widget */
  53.  
  54. static int stencilOn = 1;
  55.  
  56. /* function declarations */
  57.  
  58. void 
  59.     createToplevel(void),
  60.     drawScene(void),
  61.     setMatrix(void),
  62.     animation(void),
  63.     exposeCB(Widget,XtPointer,XtPointer),
  64.     resizeCB(Widget,XtPointer,XtPointer),
  65.     initCB(Widget,XtPointer,XtPointer),
  66.     inputCB(Widget,XtPointer,XtPointer),
  67.     drawWireframe(int face),
  68.     drawFilled(int face);
  69.  
  70. /* global variables */
  71.             
  72. Display       *display;             /* current display */
  73. XtAppContext  appContext;           /* X application context */
  74. float         ax,ay,az;             /* angles for animation */
  75.  
  76. Widget        toplevel,       /* toplevel shell */
  77.               glw;            /* current widget */
  78.              
  79. GLXContext    glxc;           /* current glx context */
  80.  
  81. Arg args[20];
  82. int acnt;
  83.  
  84. /* coords of a cube */
  85. static GLfloat cube[8][3] = {0.0,0.0,0.0,
  86.                 1.0,0.0,0.0,
  87.                 1.0,0.0,1.0,
  88.                 0.0,0.0,1.0,
  89.                 1.0,1.0,0.0,
  90.                 1.0,1.0,1.0,
  91.                 0.0,1.0,1.0,
  92.                 0.0,1.0,0.0};
  93.  
  94. static int faceIndex[6][4] = {0,1,2,3,
  95.                   1,4,5,2,
  96.                   4,7,6,5,
  97.                   7,0,3,6,
  98.                   3,2,5,6,
  99.                   7,4,1,0};
  100. void 
  101. main(int argc, char** argv)
  102. {
  103.     XtToolkitInitialize();
  104.     appContext = XtCreateApplicationContext();
  105.     display    = XtOpenDisplay(appContext, NULL, "Ostencil","ostencil",NULL,0,
  106.                               &argc,argv);
  107.     if (!display) {
  108.         printf("%s : Unable to open display\n",argv[0]);
  109.         exit(0);
  110.     }
  111.  
  112.     printf("\n---------------------------------------------\n");
  113.     printf("OpenGL stencil example \n\n");
  114.     printf("Press:  left   button for animation\n\
  115.         middle button to turn OFF stenciling\n\
  116.         right  button to turn ON  stenciling (default)\n");
  117.  
  118.     createToplevel();             /* create widget hierarchy */
  119.     XtAppMainLoop(appContext);    /* loop forever */
  120. }
  121.  
  122.  
  123. void
  124. createToplevel(void)
  125. {
  126.     Widget frame;
  127.  
  128.     acnt = 0;
  129.     XtSetArg(args[acnt],XmNminHeight, 300);acnt++;
  130.     XtSetArg(args[acnt],XmNminWidth,  300);acnt++;
  131.     XtSetArg(args[acnt],XmNminAspectX,  1);acnt++;
  132.     XtSetArg(args[acnt],XmNminAspectY,  1);acnt++;
  133.     XtSetArg(args[acnt],XmNmaxAspectX,  1);acnt++;
  134.     XtSetArg(args[acnt],XmNmaxAspectY,  1);acnt++;
  135.     toplevel  = XtAppCreateShell("openGL stencil","ostencil",
  136.                                   applicationShellWidgetClass,
  137.                                   display,args,acnt);
  138.  
  139.     /* create a frame to hold glx widget */
  140.     frame   = XtVaCreateManagedWidget("frame", 
  141.                   xmFrameWidgetClass, toplevel, 
  142.                   NULL);
  143.  
  144.     /* create a double buffer widget, in rgb mode and manage it */
  145.     acnt = 0;
  146.     XtSetArg(args[acnt], GLwNrgba,               TRUE); acnt++;
  147.     XtSetArg(args[acnt], GLwNdoublebuffer,       TRUE); acnt++;
  148.     XtSetArg(args[acnt], GLwNstencilSize,        1); acnt++;
  149.     XtSetArg(args[acnt], GLwNallocateBackground, TRUE); acnt++;
  150.     glw = GLwCreateMDrawingArea(frame, "glw", args, acnt);
  151.     XtManageChild(glw);
  152.  
  153.     /* register callbacks */
  154.     XtAddCallback(glw, GLwNginitCallback,  initCB,   NULL);
  155.  
  156.     /* realize widget hierarchy */
  157.     XtRealizeWidget(toplevel);
  158.  
  159.     /* additional callbacks */
  160.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
  161.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
  162.     XtAddCallback(glw, GLwNinputCallback,  inputCB,  NULL);
  163.  
  164. }
  165.  
  166. static float p0[] = {-5.0,-5.0,0.0};
  167. static float p1[] = {5.0,-5.0,0.0};
  168. static float p2[] = {5.0,5.0,0.0};
  169. static float p3[] = {-5.0,5.0,0.0};
  170.  
  171. void
  172. drawWireframe(face)
  173. int face;
  174. {
  175.     int i;
  176.     glBegin(GL_LINE_LOOP);
  177.     for (i=0;i<4;i++)
  178.         glVertex3fv((GLfloat *)cube[faceIndex[face][i]]);
  179.     glEnd();
  180. }
  181.  
  182. void
  183. drawFilled(face)
  184. int face;
  185. {
  186.     int i;
  187.     glBegin(GL_POLYGON);
  188.     for (i=0;i<4;i++)
  189.         glVertex3fv((GLfloat *)cube[faceIndex[face][i]]);
  190.     glEnd();
  191. }
  192.  
  193. void
  194. drawScene(void)
  195. {
  196.  
  197.     int i;
  198.     glEnable(GL_DEPTH_TEST);
  199.     glDepthFunc(GL_LEQUAL);
  200.  
  201.     glClearColor(0.0, 0.0, 0.0, 0.0);
  202.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  203.  
  204.     glPushMatrix();
  205.  
  206.     glRotatef (ax,1.0,0.0,0.0);
  207.     glRotatef (-ay,0.0, 1.0, 0.0);
  208.  
  209.     /* all the good stuff follows */
  210.  
  211.     if (stencilOn) { 
  212.     glEnable(GL_STENCIL_TEST);
  213.         glClear(GL_STENCIL_BUFFER_BIT);
  214.         glStencilMask(1);
  215.         glStencilFunc(GL_ALWAYS,0,1);
  216.         glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
  217.     }
  218.  
  219.     glColor3f (1.0, 1.0, 0.0);
  220.     for (i=0;i<6;i++) {
  221.     drawWireframe(i);
  222.         if (stencilOn) {
  223.             glStencilFunc(GL_EQUAL, 0, 1);
  224.             glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  225.         }
  226.  
  227.         glColor3f (0.0, 0.0, 0.0);
  228.     drawFilled(i);
  229.  
  230.         glColor3f (1.0, 1.0, 0.0);
  231.         if (stencilOn) {
  232.             glStencilFunc(GL_ALWAYS,0,1);
  233.             glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
  234.         }
  235.         glColor3f (1.0, 1.0, 0.0);
  236.     drawWireframe(i);
  237.     }
  238.     glPopMatrix();
  239.  
  240.     if (stencilOn) glDisable(GL_STENCIL_TEST);
  241.  
  242.     /* end of good stuff */
  243.  
  244.     glFlush();
  245.     glXSwapBuffers(XtDisplay(glw), XtWindow(glw));
  246.  
  247. }
  248.  
  249. void
  250. setMatrix(void)
  251. {
  252.     glMatrixMode(GL_PROJECTION);
  253.     glLoadIdentity();
  254.     glOrtho(-2.0,2.0,-2.0,2.0,-2.0,2.0);
  255.     glMatrixMode(GL_MODELVIEW);
  256.     glLoadIdentity();
  257. }
  258.  
  259. void
  260. animation(void)
  261. {
  262.     register int i;
  263.     /* animate the cone */
  264.  
  265.     for (i=0;i<60;i++) {
  266.         ax += 5.0;
  267.         ay -= 2.0;
  268.         az += 5.0;
  269.         if (ax >= 360)  ax = 0.0;
  270.         if (ay <= -360) ay = 0.0;
  271.         if (az >= 360)  az = 0.0;
  272.         drawScene();
  273.     }
  274. }
  275.  
  276. void 
  277. inputCB(Widget w, XtPointer client_data, XtPointer call)
  278. {
  279.     char            string[31];
  280.     XComposeStatus  composeStatus;
  281.     KeySym keysym;
  282.     GLwDrawingAreaCallbackStruct *call_data;
  283.  
  284.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  285.  
  286.     switch(call_data->event->type) {
  287.     case ButtonPress:
  288.         switch (call_data->event->xbutton.button) {
  289.         case Button1:
  290.         animation();
  291.             break;
  292.         case Button2 :
  293.         stencilOn = 0;
  294.         XtVaSetValues(toplevel,XmNtitle, "Stencil Disabled",NULL);
  295.         drawScene();
  296.             break;
  297.         case Button3 :
  298.         stencilOn = 1;
  299.         XtVaSetValues(toplevel,XmNtitle, "Stencil Enabled",NULL);
  300.         drawScene();
  301.             break;
  302.         }
  303.         break;
  304.     case KeyPress :
  305.         XLookupString((XKeyEvent *)call_data->event,string,
  306.                       30,&keysym,&composeStatus);
  307.         switch(keysym) {
  308.         case XK_Escape :
  309.             exit(0);
  310.             break;
  311.         }
  312.     break;
  313.     default:
  314.         break;
  315.     }
  316. }
  317.  
  318. void 
  319. resizeCB(Widget w, XtPointer client_data, XtPointer call)
  320. {
  321.     GLwDrawingAreaCallbackStruct *call_data;
  322.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  323.  
  324.     GLwDrawingAreaMakeCurrent(w, glxc);
  325.     glViewport(0, 0, call_data->width, call_data->height);
  326.     setMatrix();
  327.  
  328.     drawScene();
  329. }
  330.  
  331. void 
  332. exposeCB(Widget w, XtPointer client_data, XtPointer call)
  333. {
  334.     GLwDrawingAreaCallbackStruct *call_data;
  335.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  336.  
  337.  
  338.     GLwDrawingAreaMakeCurrent(w, glxc);
  339.     glViewport(0, 0, call_data->width, call_data->height);
  340.     drawScene();
  341. }
  342.  
  343. void
  344. initCB(Widget w, XtPointer client_data, XtPointer call)
  345. {
  346.     XVisualInfo *vi;
  347.  
  348.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  349.     XtGetValues(w, args, 1);
  350.  
  351.     glxc = glXCreateContext(XtDisplay(w), vi, 0, GL_TRUE);
  352.  
  353.     ax = 10.0;
  354.     ay = -10.0;
  355.     az = 0.0;
  356. }
  357.